package keer.httpinterface.proxy;

import keer.httpinterface.http.ContentTypes;
import keer.httpinterface.http.HttpBody;
import keer.httpinterface.http.HttpContentType;
import keer.httpinterface.http.HttpParams;
import keer.httpinterface.utils.StringUtils;

import java.util.Arrays;

/**
 * TextContentTypeBodyReader类继承自ContentTypeBodyReader，专门用于处理文本类型的HTTP消息体
 * @see ContentTypeBodyReader
 * @see HttpBody
 * @see HttpContentType
 * @see HttpParams
 *
 * @author Keer
 * @since 1.0.0
 */
public class TextContentTypeBodyReader extends ContentTypeBodyReader {
    /**
     * 重写read0方法，用于读取HTTP消息体，并将其转换为指定字符集的字节数组
     *
     * @param contentType HTTP消息的内容类型
     * @param params HTTP请求的参数
     * @return 返回处理后的HTTP消息体
     * @throws Exception 如果读取或转换过程中发生错误，则抛出异常
     */
    @Override
    protected final HttpBody read0(HttpContentType contentType, HttpParams params) throws Exception {
        // 将参数转换为字符串
        String text = convertToString(params, contentType);
        // 输出转换后的字符串，供调试使用
        System.out.println(text);
        // 如果字符串为null，则将其设置为空字符串，否则转换其字符集
        text = text == null ? "" : StringUtils.convertCharset(text, contentType.getCharset());
        // 将字符串转换为字节数组，并创建新的HttpBody对象
        return HttpBody.bytesBody(contentType, text.getBytes(contentType.getCharset()));
    }

    /**
     * 将HTTP请求的参数转换为字符串
     *
     * @param params HTTP请求的参数
     * @param contentType HTTP消息的内容类型
     * @return 返回转换后的字符串
     * @throws Exception 如果转换过程中发生错误，则抛出异常
     */
    public String convertToString(HttpParams params, HttpContentType contentType) throws Exception {
        StringBuilder builder = new StringBuilder();
        // 遍历所有参数，并将其添加到StringBuilder中
        for (Object[] v : params.allParameters().values()) {
            builder.append(v == null ? "" : Arrays.deepToString(v));
        }
        return builder.toString();
    }

    /**
     * 返回当前读取器处理的内容类型
     *
     * @return 返回内容类型字符串
     */
    @Override
    protected String contentType() {
        return ContentTypes.TEXT_PLAIN;
    }


    /**
     * JsonContentTypeBodyReader类继承自TextContentTypeBodyReader，专门用于处理JSON类型的HTTP消息体
     *
     * @author Keer
     * @since 1.0.0
     */
    public static class JsonContentTypeBodyReader extends TextContentTypeBodyReader {
        /**
         * 重写convertToString方法，将HTTP请求的参数转换为JSON格式的字符串
         *
         * @param params HTTP请求的参数
         * @param contentType HTTP消息的内容类型
         * @return 返回转换后的JSON格式字符串
         * @throws Exception 如果转换过程中发生错误，则抛出异常
         */
        @Override
        public String convertToString(HttpParams params, HttpContentType contentType) throws Exception {
            return JsonCodec.encodeParams(params);
        }

        /**
         * 返回当前读取器处理的内容类型
         *
         * @return 返回内容类型字符串
         */
        @Override
        protected String contentType() {
            return ContentTypes.APPLICATION_JSON;
        }
    }

    /**
     * FormUrlEncodedContentTypeBodyReader类继承自TextContentTypeBodyReader，专门用于处理表单URL编码类型的HTTP消息体
     *
     * @author Keer
     * @since 1.0.0
     */
    public static class FormUrlEncodedContentTypeBodyReader extends TextContentTypeBodyReader {
        /**
         * 重写convertToString方法，将HTTP请求的参数转换为表单URL编码格式的字符串
         *
         * @param params HTTP请求的参数
         * @param contentType HTTP消息的内容类型
         * @return 返回转换后的表单URL编码格式字符串
         * @throws Exception 如果转换过程中发生错误，则抛出异常
         */
        @Override
        public String convertToString(HttpParams params, HttpContentType contentType) throws Exception {
            return params.queryString(contentType.getCharset());
        }

        /**
         * 返回当前读取器处理的内容类型
         *
         * @return 返回内容类型字符串
         */
        @Override
        protected String contentType() {
            return ContentTypes.FORM_URLENCODED;
        }
    }
}
